其他
Istio 运维实战系列(2):让人头大的『无头服务』-上
什么是『无头服务』?
Istio 中『无头服务』的 mTLS 故障
kubectl logs -f redis-client-6d4c6c975f-bm5w6 -c istio-proxy
[2020-09-12T13:38:23.077Z] "- - -" 0 UF,URX "-" "-" 0 0 1001 - "-" "-" "-" "-" "10.1.1.24:6379" outbound|6379||redis.default.svc.cluster.local - 10.1.1.24:6379 10.1.1.25:45940 - -
kubectl exec redis-client-6d4c6c975f-bm5w6 -c istio-proxy curl http://127.0.0.1:15000/config_dump
{
"version_info": "2020-09-13T00:33:43Z/5",
"cluster": {
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
"name": "outbound|6379||redis.default.svc.cluster.local",
"type": "ORIGINAL_DST",
"connect_timeout": "1s",
"lb_policy": "CLUSTER_PROVIDED",
"circuit_breakers": {
...
},
# mTLS 相关设置
"transport_socket": {
"name": "envoy.transport_sockets.tls",
"typed_config": {
"@type": "type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext",
"common_tls_context": {
"alpn_protocols": [
"istio-peer-exchange",
"istio"
],
# 访问 Redis 使用的客户端证书
"tls_certificate_sds_secret_configs": [
{
"name": "default",
"sds_config": {
"api_config_source": {
"api_type": "GRPC",
"grpc_services": [
{
"envoy_grpc": {
"cluster_name": "sds-grpc"
}
}
]
}
}
}
],
"combined_validation_context": {
"default_validation_context": {
# 用于验证 Redis 服务器身份的 spiffe indentity
"verify_subject_alt_name": [
"spiffe://cluster.local/ns/default/sa/default"
]
},
# 用于验证 Redis 服务器的根证书
"validation_context_sds_secret_config": {
"name": "ROOTCA",
"sds_config": {
"api_config_source": {
"api_type": "GRPC",
"grpc_services": [
{
"envoy_grpc": {
"cluster_name": "sds-grpc"
}
}
]
}
}
}
}
},
"sni": "outbound_.6379_._.redis.default.svc.cluster.local"
}
},
"filters": [
{
...
}
]
},
"last_updated": "2020-09-13T00:33:43.862Z"
}
{
"version_info": "2020-09-13T00:32:39Z/4",
"cluster": {
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
"name": "outbound|8080||awesome-app.default.svc.cluster.local",
"type": "EDS",
"eds_cluster_config": {
"eds_config": {
"ads": {}
},
"service_name": "outbound|8080||awesome-app.default.svc.cluster.local"
},
"connect_timeout": "1s",
"circuit_breakers": {
...
},
...
# mTLS 相关的配置
"transport_socket_matches": [
{
"name": "tlsMode-istio",
"match": {
"tlsMode": "istio" #对带有 "tlsMode": "istio" lable 的 endpoint,启用 mTLS
},
"transport_socket": {
"name": "envoy.transport_sockets.tls",
"typed_config": {
"@type": "type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext",
"common_tls_context": {
"alpn_protocols": [
"istio-peer-exchange",
"istio",
"h2"
],
"tls_certificate_sds_secret_configs": [
{
"name": "default",
"sds_config": {
"api_config_source": {
"api_type": "GRPC",
"grpc_services": [
{
"envoy_grpc": {
"cluster_name": "sds-grpc"
}
}
]
}
}
}
],
"combined_validation_context": {
"default_validation_context": {},
"validation_context_sds_secret_config": {
"name": "ROOTCA",
"sds_config": {
"api_config_source": {
"api_type": "GRPC",
"grpc_services": [
{
"envoy_grpc": {
"cluster_name": "sds-grpc"
}
}
]
}
}
}
}
},
"sni": "outbound_.6379_._.redis1.dubbo.svc.cluster.local"
}
}
},
{
"name": "tlsMode-disabled",
"match": {}, # 对所有其他的 enpoint,不启用 mTLS,使用 plain TCP 进行连接
"transport_socket": {
"name": "envoy.transport_sockets.raw_buffer"
}
}
]
},
"last_updated": "2020-09-13T00:32:39.535Z"
}
查看 Istio 的相关源代码(https://github.com/istio/istio/blob/514fb926e32fb95d8ee9b63d1741bf399c386a5e/pkg/kube/inject/webhook.go#L570),可以得知,当 Istio webhook 向 Pod 中注入 Envoy Sidecar 时,会同时为 Pod 添加一系列 label,其中就包括 "tlsMode" : "istio" 这个 label,如下面的代码片段所示:
patchLabels := map[string]string{
label.TLSMode: model.IstioMutualTLSModeLabel,
model.IstioCanonicalServiceLabelName: canonicalSvc,
label.IstioRev: revision,
model.IstioCanonicalServiceRevisionLabelName: canonicalRev,
}
(https://github.com/istio/istio/issues/21964)
解决方案
kind: DestinationRule
metadata:
name: redis-disable-mtls
spec:
host: redis.default.svc.cluster.local
trafficPolicy:
tls:
mode: DISABLE
{
"version_info": "2020-09-13T09:02:28Z/7",
"cluster": {
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
"name": "outbound|6379||redis.dubbo.svc.cluster.local",
"type": "ORIGINAL_DST",
"connect_timeout": "1s",
"lb_policy": "CLUSTER_PROVIDED",
"circuit_breakers": {
...
},
"metadata": {
"filter_metadata": {
"istio": {
"config": "/apis/networking.istio.io/v1alpha3/namespaces/dubbo/destination-rule/redis-disable-mtls"
}
}
},
"filters": [
{
"name": "envoy.filters.network.upstream.metadata_exchange",
"typed_config": {
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
"type_url": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange",
"value": {
"protocol": "istio-peer-exchange"
}
}
}
]
},
"last_updated": "2020-09-13T09:02:28.514Z"
}
小结
附录
如何为服务网格选择入口网关? Understanding Envoy Proxy HTTP Access Logs:https://blog.getambassador.io/understanding-envoy-proxy-and-ambassador-http-access-logs-fee7802a2ec5 一文带你彻底厘清 Isito 中的证书工作机制 Istio 运维实战系列(1):应用容器对 Envoy Sidecar 的启动依赖问题